package framework.controller;

import java.util.*;
import java.awt.event.ActionEvent;

import framework.utils.*;
import framework.utils.dto.*;
import framework.model.*;
import framework.event.CustomEvent;
import framework.gui.*;

public class LobbyController extends ServerController {

	/**********************
	 *** GLOBAL METHODS ***
	 *********************/
	
	/**
	 * Initialize LobbyController 
	 * @method LobbyController (Constructor)
	 * @param <Model> model
	 */
	public LobbyController(LobbyModel model) {
		super(model);
		super.setCurrentListener(this);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		CustomEvent event = (CustomEvent)e;
		switch(e.getActionCommand()) {
			case "PLAYERLIST" :
				this.handlePlayersResponse(event.getList());
			break;
			case "GAMELIST" :
				this.handleGamesResponse(event.getList());
			break;
			case "CHALLENGE" :
				this.handleChallengeResponse(event.getList());
			break;
			case "MATCH" :
				this.handleMatchResponse(event.getList());
			break;
		}
	}
	
	/**********************
	 *** GETTER METHODS ***
	 *********************/
	
	@Override
	protected LobbyModel getModel() {
		return (LobbyModel) super.getModel();
	};
	
	/**********************
	 *** HANDLE METHODS ***
	 *********************/
	
	/**
	 * Request to GameServer for retrieving PlayerList
	 * @method handlePlayersRequest
	 */
	public void handlePlayersRequest() {
		//If request not already fired
		super.sendCommand("get playerlist");
	};
	
	/**
	 * Request to GameServer for getting GameList
	 * @method handleGamesRequest
	 */
	public void handleGamesRequest() {
		//If request not already fired
		super.sendCommand("get gamelist");
	};
	
	/**
	 * Request to GameServer to challenge player
	 * @method handleChallengeRequest
	 * @param <String> playerName
	 * @param <String> gameType
	 */
	public void handleChallengeRequest(String playerName, String gameType) {
		//If request not already fired
		super.sendCommand("challenge \"" + playerName + "\" \"" + gameType + "\"");
	};
	
	/**
	 * Request to GameServer to accept challenge request form player
	 * @method handleChallengeAcceptRequest
	 * @param <String> playerName
	 * @param <String> gameType
	 */
	public void handleChallengeAcceptRequest(Challenge challenge) {
		//If request not already fired
		super.sendCommand("challenge accept " + challenge.getChallengeID());
	};
	
	/**
	 * Remove challenge from lobby model
	 * @method handleChallengeRemoveRequest
	 */
	public void handleChallengeRemoveRequest(Challenge challenge) {
		this.getModel().removeChallenge(challenge);
	};
	
	/**
	 * Remove all challenge from lobby model
	 * @method handleChallengeRemoveAllRequest
	 */
	public void handleChallengeRemoveAllRequest() {
		this.getModel().clearChallenges();
	};
	
	
	/**
	 * Response from GameServer for retrieving PlayerList
	 * @method handlePlayersResponse
	 */
	private void handlePlayersResponse(ArrayList<String> playerList) {
		if(!playerList.isEmpty()) {
			this.getModel().getPlayers().removeAll(this.getModel().getPlayers());
			this.getModel().setPlayers(playerList);
		};
	};
	
	/**
	 * Response from GameServer for getting GameList
	 * @method handleGamesResponse
	 */
	private void handleGamesResponse(ArrayList<String> gameList) {
		if(!gameList.isEmpty()) {
			this.getModel().setGames(gameList);
		};
	};

	/**
	 * Response from GameServer when player challenges you
	 * @method handleChallengeResponse
	 */
	private void handleChallengeResponse(ArrayList<String> challenge) {
		if(challenge.size() == 3) {
			this.getModel().addChallenge(new Challenge(challenge.get(0), challenge.get(1), Integer.parseInt(challenge.get(2))));
		}
	};

	/**
	 * Response from GameServer for accepting challenge 
	 * @method handleMatchResponse
	 */
	public void handleMatchResponse(ArrayList<String> match) {
		if(match.size() == 3) {
			//PlayerOne
			String playerOne = String.valueOf(match.get(1));
			//PlayerTwo
			String playerTwo = String.valueOf(match.get(2).toString().equals(playerOne) ? UserPreferences.getProperty("username") : match.get(2));
			//Load Game
			this.getModel().setInGame(true);
			//New GameGUI
			new GameGUI(match.get(0), playerOne, playerTwo);
		}
	};
	
};
